package com.tools.common.object.json.deserializer;

import cn.hutool.core.date.DateTime;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.tools.common.object.DateKit;
import com.tools.common.object.Note;
import com.tools.common.object.json.JsonKit;
import com.tools.common.object.string.VerifyKit;

import java.io.IOException;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;

/**
 * 日期时间类的反序列化处理器
 * */
@Note("日期时间类的反序列化处理器")
public class DateTimeHandler {

    private DateTimeHandler() {}

    @Note("jdk1.8 的日期时间类 LocalDateTime，如果目标字段值不是时间戳请注意日期时间格式为：yyyy-MM-dd HH:mm:ss")
    public static StdDeserializer<LocalDateTime> localDateTimeDeserializer() {
        return new StdDeserializer<LocalDateTime>(LocalDateTime.class) {
            @Override
            public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                String time = jsonParser.getValueAsString();
                if(VerifyKit.isInteger(time)) {
                    return DateKit.localDateTime(Long.parseLong(time));
                }
                if(JsonKit.DEFAULT_DATETIME_FORMATTER == null) {
                    throw new ClassCastException("无法将 【" + time + "】 转为 LocalDateTime 对象。因为默认格式化工具设置为了时间戳（timestamp）");
                }
                return LocalDateTime.parse(time, JsonKit.DEFAULT_DATETIME_FORMATTER);
            }
        };
    }


    @Note("jdk1.8 的日期类 LocalDate，如果目标字段值不是时间戳请注意日期时间格式为：yyyy-MM-dd")
    public static StdDeserializer<LocalDate> localDateDeserializer() {
        return new StdDeserializer<LocalDate>(LocalDate.class) {
            @Override
            public LocalDate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                String time = jsonParser.getValueAsString();
                if(VerifyKit.isInteger(time)) {
                    return DateKit.localDate(Long.parseLong(time));
                }
                if(JsonKit.DEFAULT_DATE_FORMATTER == null) {
                    throw new ClassCastException("无法将 【" + time + "】 转为 LocalDate 对象。因为默认格式化工具设置为了时间戳（timestamp）");
                }
                return LocalDate.parse(time, JsonKit.DEFAULT_DATE_FORMATTER);
            }
        };
    }

    @Note("jdk1.8 的时间类 LocalTime，如果目标字段值不是时间戳请注意日期时间格式为：HH:mm:ss")
    public static StdDeserializer<LocalTime> localTimeDeserializer() {
        return new StdDeserializer<LocalTime>(LocalTime.class) {
            @Override
            public LocalTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                String time = jsonParser.getValueAsString();
                if(VerifyKit.isInteger(time)) {
                    return DateKit.localTime(Long.parseLong(time));
                }
                if(JsonKit.DEFAULT_TIME_FORMATTER == null) {
                    throw new ClassCastException("无法将 【" + time + "】 转为 LocalTime 对象。因为默认格式化工具设置为了时间戳（timestamp）");
                }
                return LocalTime.parse(time, JsonKit.DEFAULT_TIME_FORMATTER);
            }
        };
    }


    @Note("Date 对象，根据字符串兼容时间戳或者日期时间字符串的转换，" +
            "如果目标字段值不是时间戳请注意日期时间格式为：yyyy-MM-dd HH:mm:ss")
    public static StdDeserializer<Date> dateDeserializer() {
        return new StdDeserializer<Date>(Date.class) {
            @Override
            public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                String time = jsonParser.getValueAsString();
                if(VerifyKit.isInteger(time)) {
                    return new Date(Long.parseLong(time));
                }
                if(JsonKit.DEFAULT_DATETIME_FORMATTER == null) {
                    throw new ClassCastException("无法将 【" + time + "】 转为 java.util.Date 对象，因为默认格式化工具设置为了时间戳（timestamp）");
                }
                return DateKit.date(time, JsonKit.DEFAULT_DATETIME_FORMATTER);
            }
        };
    }


    @Note("sql 包的 Date 对象，根据字符串兼容时间戳或者日期时间字符串的转换，" +
            "如果目标字段值不是时间戳请注意日期时间格式为：yyyy-MM-dd HH:mm:ss")
    public static StdDeserializer<java.sql.Date> sqlDateDeserializer() {
        return new StdDeserializer<java.sql.Date>(java.sql.Date.class) {
            @Override
            public java.sql.Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                String time = jsonParser.getValueAsString();
                if(VerifyKit.isInteger(time)) {
                    return new java.sql.Date(Long.parseLong(time));
                }
                if(JsonKit.DEFAULT_DATETIME_FORMATTER == null) {
                    throw new ClassCastException("无法将 【" + time + "】 转为 java.sql.Date 对象，因为默认格式化工具设置为了时间戳（timestamp）");
                }
                Date date = DateKit.date(time, JsonKit.DEFAULT_DATETIME_FORMATTER);
                return new java.sql.Date(date.getTime());
            }
        };
    }

    @Note("sql 包的 Timestamp 对象，根据字符串兼容时间戳或者日期时间字符串的转换，" +
            "如果目标字段值不是时间戳请注意日期时间格式为：yyyy-MM-dd HH:mm:ss")
    public static StdDeserializer<Timestamp> timestampDeserializer() {
        return new StdDeserializer<Timestamp>(Timestamp.class) {
            @Override
            public Timestamp deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                String time = jsonParser.getValueAsString();
                if(VerifyKit.isInteger(time)) {
                    return new Timestamp(Long.parseLong(time));
                }
                if(JsonKit.DEFAULT_DATETIME_FORMATTER == null) {
                    throw new ClassCastException("无法将 【" + time + "】 转为 java.sql.Timestamp 对象，因为默认格式化工具设置为了时间戳（timestamp）");
                }
                Date date = DateKit.date(time, JsonKit.DEFAULT_DATETIME_FORMATTER);
                return new Timestamp(date.getTime());
            }
        };
    }


    @Note("cn.hutool.core.date 包的 DateTime 对象，根据字符串兼容时间戳或者日期时间字符串的转换，" +
            "如果目标字段值不是时间戳请注意日期时间格式为：yyyy-MM-dd HH:mm:ss")
    public static StdDeserializer<DateTime> huToolDateTimeDeserializer() {
        return new StdDeserializer<DateTime>(DateTime.class) {
            @Override
            public DateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                String time = jsonParser.getValueAsString();
                if(VerifyKit.isInteger(time)) {
                    return new DateTime(Long.parseLong(time));
                }
                if(JsonKit.DEFAULT_DATETIME_FORMATTER == null) {
                    throw new ClassCastException("无法将 【" + time + "】 转为 cn.hutool.core.date.DateTime 对象，因为默认格式化工具设置为了时间戳（timestamp）");
                }
                return new DateTime(time, JsonKit.DEFAULT_DATETIME_FORMATTER);
            }
        };
    }

}
